package org.erp.procurement.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.erp.common.enums.SysWhetherEnum;
import org.erp.common.page.PageQueryModel;
import org.erp.procurement.constant.OrderConstant;
import org.erp.procurement.convert.OrderProductDetailsConvert;
import org.erp.procurement.entity.MiniOrder;
import org.erp.procurement.entity.OrderProductDetails;
import org.erp.procurement.entity.PcOrder;
import org.erp.procurement.entity.bo.OrderProductDetailsAddBo;
import org.erp.procurement.entity.bo.OrderProductDetailsUpdateBo;
import org.erp.procurement.entity.dto.OrderProductDetailsQueryDto;
import org.erp.procurement.entity.dto.OrderProductDetailsUnPushStockDto;
import org.erp.procurement.entity.vo.OrderProductDetailsVo;
import org.erp.procurement.mapper.MiniOrderMapper;
import org.erp.procurement.mapper.OrderProductDetailsMapper;
import org.erp.procurement.mapper.PcOrderMapper;
import org.erp.procurement.service.OrderProductDetailsService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @author libin
 * @version 1.0
 * @description:
 * @date 2025/11/5 17:05
 **/
@Log4j2
@Service
@AllArgsConstructor
public class OrderProductDetailsServiceImpl extends ServiceImpl<OrderProductDetailsMapper, OrderProductDetails> implements OrderProductDetailsService {

    private final OrderProductDetailsConvert orderProductDetailsConvert;

    private final MiniOrderMapper miniOrderMapper;

    private final PcOrderMapper pcOrderMapper;

    @Override
    public PageQueryModel<OrderProductDetailsVo> pageList(OrderProductDetailsQueryDto orderProductDetailsQueryDto) {
        Page<OrderProductDetails> page = this.page(orderProductDetailsQueryDto.buildPage()
                , new QueryWrapper<OrderProductDetails>().lambda()
                        .like(StringUtils.isNotBlank(orderProductDetailsQueryDto.getOrderNo()), OrderProductDetails::getOrderNo, orderProductDetailsQueryDto.getOrderNo())
                        .like(StringUtils.isNotBlank(orderProductDetailsQueryDto.getProductName()), OrderProductDetails::getProductName, orderProductDetailsQueryDto.getProductName())
                        .like(StringUtils.isNotBlank(orderProductDetailsQueryDto.getProductImei()), OrderProductDetails::getProductImei, orderProductDetailsQueryDto.getProductImei())
                        .like(StringUtils.isNotBlank(orderProductDetailsQueryDto.getProductCode()), OrderProductDetails::getProductCode, orderProductDetailsQueryDto.getProductCode())
                        .like(StringUtils.isNotBlank(orderProductDetailsQueryDto.getThirdOrderNo()), OrderProductDetails::getThirdOrderNo, orderProductDetailsQueryDto.getThirdOrderNo())
                        .eq(null != orderProductDetailsQueryDto.getIsSell(), OrderProductDetails::getIsSell, orderProductDetailsQueryDto.getIsSell())
                        .eq(null != orderProductDetailsQueryDto.getCheckStatus(), OrderProductDetails::getCheckStatus, orderProductDetailsQueryDto.getCheckStatus())
                        .like(StringUtils.isNotBlank(orderProductDetailsQueryDto.getCheckPerson()), OrderProductDetails::getCheckPerson, orderProductDetailsQueryDto.getCheckPerson())
                        .ge(null != orderProductDetailsQueryDto.getStartTime(), OrderProductDetails::getCreateTime, orderProductDetailsQueryDto.getStartTime())
                        .le(null != orderProductDetailsQueryDto.getEndTime(), OrderProductDetails::getCreateTime, orderProductDetailsQueryDto.getEndTime()));
        return PageQueryModel.of(page.getPages(), page.getRecords().stream()
                .map(orderProductDetailsConvert::ConvertVo).toList());
    }

    @Override
    public List<OrderProductDetailsVo> findByOrderNo(String orderNo) {
        return this.list(new QueryWrapper<OrderProductDetails>().lambda()
                        .eq(StringUtils.isNotBlank(orderNo), OrderProductDetails::getOrderNo, orderNo))
                .stream().map(orderProductDetailsConvert::ConvertVo).toList();
    }

    public void buildParam(OrderProductDetailsAddBo orderProductDetailsAddBo, OrderProductDetails orderProductDetails) {
        orderProductDetails.setBrandId(orderProductDetailsAddBo.getBrandId());
        orderProductDetails.setCategoryId(orderProductDetailsAddBo.getCategoryId());
        orderProductDetails.setModelId(orderProductDetailsAddBo.getModelId());
        orderProductDetails.setSeriesId(orderProductDetailsAddBo.getSeriesId());
        orderProductDetails.setLevelId(orderProductDetailsAddBo.getLevelId());
        orderProductDetails.setProductName(orderProductDetailsAddBo.getProductName());
        orderProductDetails.setProductImei(orderProductDetailsAddBo.getProductImei());
        orderProductDetails.setProductCode(orderProductDetailsAddBo.getProductCode());
        orderProductDetails.setProductColor(orderProductDetailsAddBo.getProductColor());
        orderProductDetails.setProductStorage(orderProductDetailsAddBo.getProductStorage());
        orderProductDetails.setRecycleAmount(orderProductDetailsAddBo.getRecycleAmount());
        orderProductDetails.setThirdOrderNo(orderProductDetailsAddBo.getThirdOrderNo());
        orderProductDetails.setIsSell(null != orderProductDetailsAddBo.getIsSell() ? orderProductDetailsAddBo.getIsSell() : SysWhetherEnum.NO.getCode());
        orderProductDetails.setCheckStatus(SysWhetherEnum.NO.getCode());
        orderProductDetails.setCheckPerson("张三");
    }

    public List<OrderProductDetails> buildOrderProductDetailsList(List<OrderProductDetailsAddBo> orderProductDetailsAddBoList, String orderNo) {
        List<OrderProductDetails> orderProductDetailsList = new ArrayList<>();
        orderProductDetailsAddBoList.forEach(o -> {
            OrderProductDetails details = new OrderProductDetails();
            details.setOrderNo(orderNo);
            this.buildParam(o, details);
            orderProductDetailsList.add(details);
        });
        return orderProductDetailsList;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateAmount(OrderProductDetailsUpdateBo orderProductDetailsUpdateBo) {
        Integer recycleAmount = orderProductDetailsUpdateBo.getRecycleAmount();
        if (null == recycleAmount) {
            recycleAmount = 0;
        }
        OrderProductDetails orderProductDetails = this.getById(orderProductDetailsUpdateBo.getId());
        if (orderProductDetails.getOrderNo().startsWith(OrderConstant.MINI_PREFIX)) {
            MiniOrder miniOrder = miniOrderMapper.selectOne(new QueryWrapper<MiniOrder>().lambda()
                    .eq(MiniOrder::getOrderNo, orderProductDetails.getOrderNo()));
            miniOrder.setRecycleAmount(miniOrder.getRecycleAmount() - orderProductDetails.getRecycleAmount() + recycleAmount);
            miniOrderMapper.updateById(miniOrder);
        } else if (orderProductDetails.getOrderNo().startsWith(OrderConstant.PC_PREFIX)) {
            PcOrder pcOrder = pcOrderMapper.selectOne(new QueryWrapper<PcOrder>().lambda()
                    .eq(PcOrder::getOrderNo, orderProductDetails.getOrderNo()));
            pcOrder.setRecycleAmount(pcOrder.getRecycleAmount() - orderProductDetails.getRecycleAmount() + recycleAmount);
            pcOrderMapper.updateById(pcOrder);
        }
        orderProductDetails.setRecycleAmount(recycleAmount);
        this.updateById(orderProductDetails);
    }

    @Override
    public PageQueryModel<OrderProductDetailsVo> findUnPushStock(OrderProductDetailsUnPushStockDto orderProductDetailsUnPushStockDto) {
        Page<OrderProductDetails> page = this.page(orderProductDetailsUnPushStockDto.buildPage(), new QueryWrapper<OrderProductDetails>().lambda()
                .eq(OrderProductDetails::getPushStock, SysWhetherEnum.NO.getCode())
                .in(OrderProductDetails::getProductCode, orderProductDetailsUnPushStockDto.getProductCodeList()));
        return PageQueryModel.of(page.getPages(), page.getRecords().stream()
                .map(orderProductDetailsConvert::ConvertVo).toList());
    }
}
